#! /usr/bin/env python
# -*- coding: utf-8 -*-

# *************************************************************
#  Copyright (c) Huoty - All rights reserved
#
#      Author: Huoty <sudohuoty@gmail.com>
#  CreateTime: 2016-10-19 22:54:53
# *************************************************************

"""请求处理器"""

import os
import json
import time

import tornado.web
import tornado.auth
from tornado.escape import utf8, json_decode

from ..utils import log
from ..utils import sha1, md5, AESCipher, json_dumps
from .base import JsonResponse, api_scheduler
from .wechat import dami_baby_wechat as wechat


class BaseHandler(tornado.web.RequestHandler):
    def __init__(self, application, request, **kwargs):
        super(BaseHandler, self).__init__(application, request, **kwargs)

        # 提取所有请求参数
        self.args = {k: utf8(b','.join(v)) for k, v in self.request.arguments.items()}

        # 保存 JSON 格式的请求体
        self.json = None

    def prepare(self):
        if self.request.headers.get("Content-Type", "").startswith("application/json"):
            try:
                self.json = json_decode(utf8(self.request.body))
            except ValueError as e:
                log.warning("e")
        pass


class IndexHandler(BaseHandler):
    """首页"""
    def get(self):
        self.write("This is OK!")


class ApiHandler(BaseHandler):
    """公共 API 处理器"""
    def initialize(self, db):
        self.db = db
        self.response = JsonResponse()  # 初始化 json 响应体
        self.params = None  # 保存请求数据

    def prepare(self):
        super(ApiHandler, self).prepare()

        if self.json is None or set(self.json.keys()) != {"key", "timestamp", "data" }:
            raise tornado.web.HTTPError(400)

        timestamp = self.json["timestamp"]
        if not timestamp or (time.time() - int(timestamp)) > 60 * 10:
            raise tornado.web.HTTPError(400)

        apikey = self.json["key"]
        if apikey != os.environ["KIBOT_TEST_KEY"]:
            log.warning("not exist key: %s", self.json)
            self.response.code = 12001
            self.respond()

        secret = os.environ["KIBOT_TEST_SEC"]
        aes_key = md5(secret + timestamp + apikey)
        try:
            aes = AESCipher(aes_key)
            self.params = json.loads(aes.decrypt(self.json["data"]))
        except Exception:
            log.warning("decrypt failed: %s" % self.json)
            self.response.code = 12003
            self.respond()

        if set(self.params.keys()) != {"user", "info"}:
            log.warning("incorrect data format: %s", self.params)
            self.response.code = 12005
            self.respond()

    def post(self):
        userid = 1000
        self.response.data = api_scheduler(self.params["info"], userid)
        self.respond()

    def respond(self):
        self.write(self.response.to_json())

    def write_error(self, status_code, **kwargs):
        if self.settings.get("debug"):
            # in debug mode
            super(ApiHandler, self).write_error(status_code, **kwargs)
        else:
            if status_code >= 500:
                self.set_status(200)
                self.response.code = 12050
                self.respond()
            else:
                super(ApiHandler, self).write_error(status_code, **kwargs)


class WechatHandler(BaseHandler):
    """微信公众平台处理器"""
    def get(self):
        args = {k: b''.join(v).decode("utf-8") for k, v in self.request.arguments.items()}

        if set(args.keys()) == {"signature", "timestamp", "nonce", "echostr"}:
            if wechat.check_signature(args["signature"], args["timestamp"], args["nonce"]):
                self.write(args["echostr"])
            else:
                self.write("Validation failure!")
        else:
            self.write(json_dumps(args))


class ChatHandler(BaseHandler):
    """Web 版聊天机器人处理器"""
    def get(self):
        pass


# Script starts from here

if __name__ == "__main__":
    pass
